/* Bitte ausf�llen
 * Name: 
 * Matrikelnummer:
 */
package pruefung;

import java.util.*;
import static com.google.common.base.Preconditions.*;

/**
 *
 * @author oelker_g
 */
public class Pruefung {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
    }
    
    public String aDummyStringForTestingJUnit(){
        return "Everything is fine!";
    }
    
    public void doNothingExceptInvokingPreconditionCheck(int i){
        checkArgument(i >= 0, "Argument was %s but expected nonnegative", i);
    }

    // Vergleich von Char-Sequenzen
    public static int compareCharLists(List<Character> list1, List<Character> list2) {

        // Precondition
        checkNotNull(list1);
        checkNotNull(list2);

        // Iteratror vereinbaren
        Iterator<Character> iter_1 = list1.iterator();
        Iterator<Character> iter_2 = list2.iterator();
        Character a,b;
        // Liste durchgehen
        while( iter_1.hasNext() && iter_2.hasNext()  ) {
            a = iter_1.next();
            b = iter_2.next();

            if( a.compareTo(b) == 0 ) {
                // a und b sind gleich
            } else if( a.compareTo(b) == 1) {
                return 1;
            } else {
                return -1;
            }
        }
        // sind beide Iteratoren leer?
        if(iter_1.hasNext()) {
            return 1;
        } else if(iter_2.hasNext()) {
            return -1;
        } else
            return 0;
    }
    // Aufgabe 2
    // Number of Leaves ermitteln
    public static int noOfDuplicateLeaves(Set<?> aSet) {
        // leere Arbeitsmap erschaffen
        HashMap<Object,Integer> workingMap = new HashMap<Object,Integer>();
        noOfDuplicateLeaves(aSet,workingMap);

        int returnValue = 0;
        Set<Object> keys = workingMap.keySet();
        for(Object o : keys) {
            if( workingMap.get(o) > 1 ) {
                returnValue +=1;
            }
        }

        return returnValue;
    }
    private static void noOfDuplicateLeaves(Set<?> aSet, HashMap<Object,Integer> resultMap) {

        Iterator<?> iter = aSet.iterator();
        
        // set Durchlaufen
        while(iter.hasNext()) {
            Object o = iter.next();
            if( o instanceof Set<?>)
            {
                // Absteigen
                noOfDuplicateLeaves((Set<?>)o,resultMap);
            } else {
                if(resultMap.containsKey( o.getClass() ) ) {
                    resultMap.put(o.getClass(), resultMap.get(o.getClass())+1);
                } else {
                    resultMap.put(o.getClass(),1);
                }
            }
        }
    }

    // SS2010
    // A1 isSorted 19:50 Uhr - 20:05 Uhr = 15 Minuten
    public static boolean isSorted(List<String>list) {
        checkNotNull(list);
        // Eine Liste mit nur einem Element ist immer sortiert
        if(list.size() == 1) return true;

        // Iterator
        Iterator<String> iter = list.iterator();
        String left = iter.next();
        
        // Alle Strings durchlaufen
        while(iter.hasNext())
        {
            String next = iter.next();
            if( left.compareTo(next) > 0 ) {
                return false;
            }
        }
        
        // kein Fehler, dann ist die Liste Sortiert
        return true;
    }

    // A2 Rekursion in Bäumen 20:05 Uhr - 20:15 Uhr = 10 Minuten
    public static int noOfAllNodes(Set<?>aSet) {
        checkNotNull(aSet);
        int returnValue = 0;

        for(Object o : aSet ) {
            // o ist wieder ein Set?
            if(o instanceof Set<?>) {
                returnValue += noOfAllNodes((Set<?>)o);
            } else {
                returnValue += 1;
            }
        }
        return returnValue;
    }

    // A3 Frequency Maps 22:30 Uhr - 22:42 Uhr
    public static Map<String,Integer> addFreqMaps(Map<String,Integer>map1, Map<String,Integer> map2) {
        // PreCheck
        checkNotNull(map1);
        checkNotNull(map2);
        // Rückgabe
        Map<String,Integer> result = new HashMap<String, Integer>();
        result.putAll(map1);

        for(String str : map2.keySet()) {
            if( result.containsKey(str)) {
                result.put(str, result.get(str)+map2.get(str) );
            } else {
                result.put(str,map2.get(str));
            }
        }

        // und ab damit
        return result;
    }
    
    // A4 interleave
    public static List<String> interleave( List<String> list1, List<String>list2 ) {
        checkNotNull(list1);
        checkNotNull(list2);
        List<String>result = new ArrayList<String>();

        Iterator<String> iter1 = list1.iterator();
        Iterator<String> iter2 = list2.iterator();
        boolean toggle = true;
        while( iter1.hasNext() || iter2.hasNext() ) {
            if( toggle ) {
                toggle = false;
                if(iter1.hasNext()) result.add( iter1.next() );
            } else {
                toggle = true;
                if(iter2.hasNext())result.add( iter2.next() );
            }
        }
        return result;

    }

    // A1 SS12
    public static int maxDepthOf(Collection<?>aColl) {
        int result = 0;
        boolean plus = false;
        for ( Object o : aColl ) {
            if( o instanceof Collection ){
                result += maxDepthOf((Collection<?>)o);
            } else { plus = true; }
        }
        if(plus) return result+1; else return result;
    }
    // A2
    public static boolean setEqual(Set<?>set, Object obj) {
        return true;
    }
}
